#include <QDomNode>
#include <QFile>
#include <QMessageBox>

#include <qgsvectorlayer.h>
#include <qgsrasterlayer.h>
#include <qgsmaplayerregistry.h>
#include <qgsmaprenderer.h>
#include <qgsmaptoolpan.h>
#include <qgsmaptoolzoom.h>
#include <qgslogger.h>


#include "profileview.h"
#include "ui_profileview.h"
#include "unique.h"
#include "dbconnection.h"

ProfileView::ProfileView(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::ProfileView)
{    
    ui->setupUi(this);
    mapCanvas = new QgsMapCanvas(0, "profile");
    mapCanvas->setCanvasColor(QColor("white"));
    mapCanvas->setVisible(true);
    mapCanvas->enableAntiAliasing(true);
    ui->mapLayout->addWidget(mapCanvas);

    mapTool.Pan = new QgsMapToolPan( mapCanvas );
    mapTool.ZoomIn = new QgsMapToolZoom( mapCanvas, false );
    mapTool.ZoomOut = new QgsMapToolZoom( mapCanvas, true );

    mapPan();

    connect(unique::inst()->QgisIface()->mapCanvas(),
            SIGNAL(extentsChanged()),
            this,
            SLOT(zoomToMainExtent())
            );

    connect(ui->btnPan, SIGNAL(clicked()), this, SLOT(mapPan()));
    connect(ui->btnZoomIn, SIGNAL(clicked()), this, SLOT(zoomIn()));
    connect(ui->btnZoomOut, SIGNAL(clicked()), this, SLOT(zoomOut()));
    connect(ui->btnFullExtent, SIGNAL(clicked()), this, SLOT(fullExtent()));
}

ProfileView::~ProfileView()
{
    delete ui;
    delete mapTool.Pan;
    delete mapTool.ZoomIn;
    delete mapTool.ZoomOut;
}

bool ProfileView::loadProject(QString fileName)
{
    QDomDocument doc( "mydoc" );
    QFile file( fileName );
    if (!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::information(0, "info", "cannot open file");
        return false;
    }
    if (!doc.setContent(&file)) {
        file.close();
        QMessageBox::information(0, "info", "cannot read file");
        return false;
    }
    file.close();

    QDomNodeList nl = doc.elementsByTagName( "maplayer" );
    QList<QgsMapCanvasLayer> layerSet;
    //QMessageBox::information(0, "info", QString("node counts %1").arg(nl.count()));
    ui->progressBarProfileLoading->setVisible(true);
    ui->progressBarProfileLoading->setMaximum(nl.count());

    for(int i=0; i<nl.count(); i++)
    {
        ui->progressBarProfileLoading->setValue(i);
        ui->progressBarProfileLoading->update();
        QDomNode node = nl.item( i );
        QDomElement element = node.toElement();
        QString type = element.attribute( "type" );

        QgsMapLayer *mapLayer = NULL;

        if ( type == "vector" )
        {
            mapLayer = new QgsVectorLayer;
        }
        else if ( type == "raster" )
        {
            //не будет тут растров
            mapLayer = new QgsRasterLayer;
        }

        if(mapLayer && mapLayer->readXML( node ))
        {
            if(mapLayer->type() == QgsMapLayer::VectorLayer)
                defaultSql.insert(mapLayer, (static_cast<QgsVectorLayer*>(mapLayer))->subsetString());
            layerSet.append( QgsMapCanvasLayer( mapLayer, true ) );
            QgsMapLayerRegistry::instance()->addMapLayer( mapLayer, false );
        }

    }
    ui->progressBarProfileLoading->setValue(0);
    ui->progressBarProfileLoading->setVisible(false);
    mapCanvas->setLayerSet(layerSet);
    fullExtent();
    return true;
}

void ProfileView::zoomToMainExtent()
{    
    QgsDebugMsg("PLDP: start zoom");
    QgsVectorLayer *vl = static_cast<QgsVectorLayer*>(unique::inst()->findLayer("stationseries"));
    if(lineloopEventID.isEmpty()) return;//водопровод не подгружен
    //QgsFeatureList *selfeatures = vl->selectedFeatures();
    if(vl)
    {

        QgsMapCanvas *canvas = unique::inst()->QgisIface()->mapCanvas();

        if(!canvas)
        {
            QgsDebugMsg("PLDP: null canvas");
            return;
        }

        QgsRectangle Extent = canvas->extent();

        QgsRectangle layerExtent = canvas->mapRenderer()->mapToLayerCoordinates(vl, Extent);


        QSqlQuery query(dbconnection::instance()->database());
        query.prepare(
                "select max(st_m(geom)) mmax, min(st_m(geom)) mmin "
                "from"
                "   (select *, (st_dumppoints(st_force_4d(geom))).geom as geom from stationseries) as inter "
                "where "
                " inter.lineloopeventid = '"+lineloopEventID+"' "
                " and st_intersects(inter.geom, "
                "               st_geomfromewkt('SRID=4326;POLYGON(("+unique::extentToWKT(layerExtent)+"))'))"
                );
        if(query.exec())
        {
            QSqlRecord rec = query.record();
            query.next();
            double xmin = query.value(rec.indexOf("mmin")).toDouble();
            double xmax = query.value(rec.indexOf("mmax")).toDouble();
            double dx = xmax-xmin;
            double ymin = mapCanvas->fullExtent().yMinimum();
            double ymax = mapCanvas->fullExtent().yMaximum();
            QgsRectangle extent(xmin-dx*.05,
                                ymin,
                                xmax+dx*.05,
                                ymax
                                );
            mapCanvas->setExtent(extent);
            QgsDebugMsg("PLDP: new extent " + extent.asWktCoordinates());
            mapCanvas->refresh();

        }
        else
            QMessageBox::information(0, "error", query.lastError().text());


    }
    QgsDebugMsg("PLDP: end zoom");
}

void ProfileView::mapPan()
{
    mapCanvas->setMapTool( mapTool.Pan );
}

void ProfileView::zoomIn()
{
    mapCanvas->setMapTool( mapTool.ZoomIn );
}

void ProfileView::zoomOut()
{
    mapCanvas->setMapTool( mapTool.ZoomOut );
}

void ProfileView::fullExtent()
{
    mapCanvas->zoomToFullExtent();
}

void ProfileView::setLineLoopEventID(QString lleid)
{
    lineloopEventID = lleid;
    for(int i=0; i<mapCanvas->layerCount(); i++)
    {
        if(mapCanvas->layer(i)->type() == QgsMapLayer::VectorLayer)
        {
            QgsVectorLayer *vlyr = static_cast<QgsVectorLayer*>(mapCanvas->layer(i));
            if(!lineloopEventID.isEmpty())
            {
                QString sql = defaultSql[vlyr];
                QString query = "lineloopeventid='"+lineloopEventID+"'";
                sql = sql.isEmpty()? query : "("+sql +") and " + query;
                vlyr->setSubsetString(sql);
            }
        }
    }
    fullExtent();
}
